package client

import (
	"context"
	serverCommon "fiberCommonUtils/common"
	"fiberCommonUtils/request"
	"fmt"
	"github.com/gofiber/fiber/v2"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/bson/primitive"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
	"mongoDB"
	"regexp"
	"strings"
)

func (c *Client) FindOneClient(ctx context.Context, filter *bson.D, opts ...*options.FindOneOptions) error {
	result := new(Client)
	err := result.GetCollection().FindOne(ctx, filter, opts...).Decode(result)
	if err != nil {
		return err
	}
	*c = *result
	return nil
}

func decodeClientCursor(ctx context.Context, cursor *mongo.Cursor) (ClientList *[]Client, err error) {
	list := make([]Client, 0)
	err = cursor.All(ctx, ClientList)
	if err != nil {
		return nil, err
	}
	return &list, err
}

func (c *Client) FindByOpenID(ctx context.Context) error {
	err := c.FindOneClient(ctx, &bson.D{{"person.auth_info.wx_open_id", c.Person.AuthInfo.WxOpenID}})
	return err
}

func (c *Client) FindByID(ctx context.Context) error {
	err := c.FindOneClient(ctx, &bson.D{{"_id", c.ID}})
	return err
}

// ReadAuthInfo 读取用户认证信息
func ReadAuthInfo(c *fiber.Ctx) error {
	_client := c.Locals("client").(*Client)
	result := make(map[string]interface{})
	result["name"] = _client.Person.Information.Name
	result["phone"] = _client.Person.Contact.Phone
	result["id_number"] = _client.Person.AuthInfo.IDNumber
	return c.JSON(serverCommon.MakeSuccessJson(result))
}

// SetAuthInfo 读取用户认证信息
func SetAuthInfo(c *fiber.Ctx) error {
	_client := c.Locals("client").(*Client)
	data := request.ParsePostLikeRequestV2(c, &struct {
		IdNumber string `json:"idNumber"`
		Name     string `json:"name" required:"true"`
	}{})
	data.Name = strings.TrimSpace(data.Name)
	data.IdNumber = strings.TrimSpace(data.IdNumber)
	if !validateIDNumber(data.IdNumber) {
		return fiber.NewError(500, "身份证号码格式不正确,"+data.IdNumber)
	}
	if len(data.Name) < 2 {
		return fiber.NewError(500, fmt.Sprint("名字太短"))
	}
	ctx, cancel := mongoDB.MongoDBTimeoutContext()
	defer cancel()
	err := _client.Update(ctx, &bson.D{
		{"$set", bson.D{
			_client.UpdateIDNumberFields(data.IdNumber),
			_client.UpdateNameFields(data.Name),
		}},
	})
	if err != nil {
		return err
	}
	return c.JSON(serverCommon.MakeSuccessJson("done"))
}

// validatePhoneNumber 验证手机号码是否符合中国大陆的手机号码格式
func validatePhoneNumber(phone string) bool {
	// 正则表达式匹配中国大陆手机号码
	// 1. 以1开头
	// 2. 第二位为3-9之间的数字
	// 3. 后面跟着9位数字
	pattern := `^1[3-9]\d{9}$`
	matched, err := regexp.MatchString(pattern, phone)
	if err != nil {
		return false
	}
	return matched
}

func validateIDNumber(idNumber string) bool {
	// 正则表达式匹配中国大陆身份证号码
	// 1. 15位或18位数字
	// 2. 18位身份证的最后一位可能是X（大小写不敏感）
	pattern := `^(\d{15}|\d{17}[\dXx])$`
	matched, err := regexp.MatchString(pattern, idNumber)
	if err != nil {
		return false
	}
	return matched
}

func MiddleWareFindClientByID(c *fiber.Ctx) error {
	ctx, cancel := mongoDB.MongoDBTimeoutContext()
	defer cancel()
	if c.Method() == "GET" {
		id := c.Query("clientID")
		var err error
		_client := &Client{}
		_client.ID, err = primitive.ObjectIDFromHex(id)
		if err != nil {
			return fiber.NewError(500, fmt.Sprint("客户id解析错误,", id, ",", err.Error()))
		}
		err = _client.FindByID(ctx)
		if err != nil {
			return fiber.NewError(500, fmt.Sprint("客户信息读取失败,", err.Error()))
		}
		c.Locals("client", _client)
		return c.Next()
	} else if c.Method() == "POST" {
		type T struct {
			ClientID primitive.ObjectID `json:"clientID" form:"clientID"`
		}
		data := request.ParsePostLikeRequestV2(c, &T{})
		_client := &Client{ID: data.ClientID}
		err := _client.FindByID(ctx)
		if err != nil {
			return fiber.NewError(500, fmt.Sprint("客户信息读取失败,", err.Error()))
		}
		c.Locals("client", _client)
		return c.Next()
	}
	return c.Next()
}
